package main

import (
	"time"

	"gofw-im/lib/hash/cityhash"
)

var defaultServer *Server

type ServerOptions struct {
	WriteWait       time.Duration
	PongWait        time.Duration
	PingPeriod      time.Duration
	MaxMessageSize  int
	ReadBufferSize  int
	WriteBufferSize int
	BroadcastSize   int
}

type Server struct {
	Buckets   []*Bucket // subkey bucket
	Options   *ServerOptions
	bucketIdx uint32
	operator  Operator
}

func InitDefaultServer() (err error) {
	buckets := make([]*Bucket, conf.Bucket.Num)
	for i := 0; i < conf.Bucket.Num; i++ {
		buckets[i] = NewBucket(&BucketOptions{
			ChannelSize:   conf.Bucket.Channel,
			RoomSize:      conf.Bucket.Room,
			RoutineAmount: conf.Bucket.RoutineAmount,
			RoutineSize:   conf.Bucket.RoutineSize,
		})
	}
	operator := new(DefaultOperator)
	defaultServer = NewServer(buckets, operator, &ServerOptions{
		WriteWait:       conf.Base.WriteWait,
		PongWait:        conf.Base.PongWait,
		PingPeriod:      conf.Base.PingPeriod,
		MaxMessageSize:  conf.Base.MaxMessageSize,
		ReadBufferSize:  conf.Base.ReadBufferSize,
		WriteBufferSize: conf.Base.WriteBufferSize,
		BroadcastSize:   conf.Base.BroadcastSize,
	})
	return
}

// NewServer returns a new Server.
func NewServer(b []*Bucket, operator Operator, options *ServerOptions) *Server {
	s := new(Server)
	s.Buckets = b
	s.Options = options
	s.bucketIdx = uint32(len(b))
	s.operator = operator
	return s
}

func (s *Server) Bucket(subKey string) *Bucket {
	idx := cityhash.CityHash32([]byte(subKey), uint32(len(subKey))) % s.bucketIdx
	// if Debug {
	// 	log.Debug("\"%s\" hit channel bucket index: %d use cityhash", subKey, idx)
	// }
	return s.Buckets[idx]
}
